﻿using System;
using System.Windows.Controls;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TinyContainer;
using TinyContainerTest.TestHelperClasses;

namespace TinyContainerTest
{
    [TestClass]
    public class ContainerTest
    {
        /// <summary>
        /// Test for container constructor.
        /// </summary>
        [TestMethod]
        public void TestConstructor()
        {
            var container = new Container();
            Assert.IsInstanceOfType(container, typeof(Container), "The expected type does not match");
        }

        /// <summary>
        /// Container attempts to resolve itself.
        /// </summary>
        [TestMethod]
        public void TestResolveSelf()
        {
            var container = new Container();
            Assert.IsInstanceOfType(container.Resolve<IContainer>(), typeof(IContainer));
        }

        /// <summary>
        /// Asserts the containers inheritance hierarchy.
        /// </summary>
        [TestMethod]
        public void TestResolveInherit()
        {
            var container = new Container();
            Assert.AreSame(container.Resolve<IContainer>(), container.Resolve<Container>());
        }


        [TestMethod]
        public void TestResolveWithSingleParam()
        {
            var container = new Container();
            Assert.IsNotNull(container.Resolve<SingleParamClass>());
        }

        [TestMethod]
        public void TestGeneralResolve()
        {
            var container = new Container();
            Assert.IsInstanceOfType(container.Resolve<Button>(), typeof(Button));
        }

        [TestMethod]
        public void TestResolveWithInterface()
        {
            var container = new Container();
            container.Register<string>("Hello World");
            container.Register<ISampleClass,SampleClass>();
            var obj = container.Resolve<ISampleClass>();
            Assert.IsNotNull(obj);
            obj.SayCheez();
        }

        [TestMethod]
        public void TestResolveWitoutRegister()
        {
            var container = new Container();

            try
            {
                var obj = container.Resolve<ISampleClass>();
                Assert.Fail("FAIL: You are not suppose to come here");
            }
            catch (Exception ex)
            {
                Assert.IsNotNull(ex);
            }
        }

        [TestMethod]
        public void TestIsRegisterTrue()
        {
            var container = new Container();
            Assert.IsTrue(container.IsRegistered<IContainer>());
        }

        [TestMethod]
        public void TestIsRegisterFalse()
        {
            var container = new Container();
            Assert.IsFalse(container.IsRegistered<Button>());
        }

        [TestMethod]
        public void TestRemove()
        {
            var container = new Container();
            container.Register<ISampleClass,SampleClass>();
            var obj1 = container.Resolve<ISampleClass>();
            container.Remove(obj1);
            var obj2 = container.Resolve<ISampleClass>();
            Assert.AreNotSame(obj1, obj2);
        }

        [TestMethod]
        public void TestDefaultImportAttribute()
        {
            var container = new Container();
            container.Register<ISampleClass, SampleClass>();
            var obj = container.Resolve<ClassWithAttr>();
            Assert.IsInstanceOfType(obj.Sample, typeof(SampleClass));
        }

        [TestMethod]
        public void TestNamedRegister()
        {
            var container = new Container();
            container.Register<ISampleClass, SampleClass>("Sample");
            var obj = container.Resolve<ISampleClass>("Sample");
            Assert.IsNotNull(obj);
        }

        [TestMethod]
        public void TestNamedRegisterFail()
        {
            var container = new Container();
            container.Register<ISampleClass, SampleClass>("Sample");
            try
            {
                var obj = container.Resolve<ISampleClass>();
                Assert.Fail("Must not be resolved");
            }
            catch (Exception ex)
            {
                Assert.IsNotNull(ex);
            }
        }

        [TestMethod]
        public void TestNamedInstance()
        {
            var container = new Container();
            container.Register<ISampleClass, SampleClass>();
            var sample = new SampleClass(container);
            container.Register<ISampleClass>(sample, "Hello");
            var obj1 = container.Resolve<ISampleClass>();
            var obj2 = container.Resolve<ISampleClass>("Hello");

            Assert.AreNotEqual(obj1, obj2);
        }

        [TestMethod]
        public void TestNamedAttribute()
        {
            var container = new Container();
            container.Register<ISampleClass, SampleClass>("Sample");
            var obj = container.Resolve<ClassWithNamedImport>();

            Assert.IsNotNull(obj.Sample);
        }
    }
}